package com.czeczek.domain.internal;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.springframework.batch.item.ItemProcessor;

import com.czeczek.domain.IndicatorQuote;
import com.czeczek.domain.Quote;
import com.czeczek.domain.dao.IndicatorsDao;
import com.czeczek.indicators.Indicator;

public class IndicatorProcessor implements ItemProcessor<Quote, IndicatorQuote> {

	private List<Indicator> indicators;
	
	//List of quotes per symbol. list contains map of quotes per indicator id
	private Map<String, Map<Long, LinkedList<Quote>>> buffer;
	
	private IndicatorsDao dao;
	
	public IndicatorProcessor() {
		buffer = new HashMap<String, Map<Long,LinkedList<Quote>>>();
	}
	
	public IndicatorsDao getDao() {
		return dao;
	}

	public void setDao(IndicatorsDao dao) {
		this.dao = dao;
	}

	public IndicatorQuote process(Quote item) throws Exception {
		Map<Long, IndicatorQuote> result = new HashMap<Long, IndicatorQuote>();
		//Fetch all indicators if there were no retrieved previously
		if (indicators == null || indicators.isEmpty()) {
			indicators = dao.getIndicators();
		}
		LinkedList<Quote> quotesList = null;
		Map<Long, LinkedList<Quote>> symbolQuotes = null;
		IndicatorQuote indicatorQuote = null;
		for(Indicator indicator: indicators) {
			if (buffer.containsKey(item.getSymbol())) {
				symbolQuotes = buffer.get(item.getSymbol());
				if (symbolQuotes.containsKey(indicator.getIndicatorId())) {
					quotesList = symbolQuotes.get(indicator.getIndicatorId());	
				} else {
					quotesList = new LinkedList<Quote>();
					quotesList.add(item);
					symbolQuotes.put(indicator.getIndicatorId(), quotesList);
				}
			} else {
				quotesList = new LinkedList<Quote>();
				quotesList.add(item);
				symbolQuotes = new HashMap<Long, LinkedList<Quote>>();
				symbolQuotes.put(indicator.getIndicatorId(), quotesList);
				buffer.put(item.getSymbol(), symbolQuotes);
			}
			indicatorQuote = indicator.execute(quotesList, item);
			if (indicatorQuote != null) {
				result.put(indicator.getIndicatorId(), indicatorQuote);
			}
		}
		//If no indicator computed for the item, return null to skip writing out this item
		//return indicatorQuotes.size() > 0 ? indicatorQuotes : null;
		return indicatorQuote;
	}

}
